<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

    <script>
        const App = function () {
            // 中间件公共的处理数据
            let context = {};
            // 中间件队列
            let middlewares = [];
            return {
                // 将中间件放入队列中
                use(fn) {
                    middlewares.push(fn);
                },
                // 调用中间件
                callback() {
                    // 初始调用 middlewares 队列中的第 1 个中间件
                    return dispatch(0);

                    function dispatch(i) {
                        // 获取要执行的中间件函数
                        let fn = middlewares[i];
                        // 执行中间件函数，回调参数是：公共数据、调用下一个中间件函数
                        // 返回一个 Promise 实例
                        return Promise.resolve(
                            fn(context, function next() {
                                dispatch(i + 1); //
                            })
                        );
                    }
                },
            };
        };

        // 测试代码
        let app = App();
        app.use(async (cxt, next) => {
            console.log("middleware_01 start"); //1
            await next();
            console.log("middleware_01 end");//6
        });
        app.use(async (cxt, next) => {
            console.log("middleware_02 start");//2
            await next();
            console.log("middleware_02 end");//5
        });
        app.use(async (cxt, next) => {
            console.log("middleware_03 start");//3
            console.log("middleware_03 end");//4
        });
        // Koa2.js 源码中，放在 http.createServer(callback) 回调中调用
        // 这里我们直接调用
        app.callback();
    </script>
</body>

</html>